package com.twu.biblioteca;

import org.springframework.stereotype.Component;

import javax.inject.Inject;
import java.util.HashMap;
import java.util.Map;

@Component
public class Biblioteca {

    private final Map<String,Book> books;
    private final Map<String,Movie> movies;

    private final Printer printer;
    private final Reader reader;
    private final Authorizer authorizer;

    private boolean shouldKeepRunningBiblioteca = true;

    @Inject
    public Biblioteca(Printer printer, Reader reader, Authorizer authorizer) {
        this.books = new HashMap<>();
        this.movies = new HashMap<>();
        this.printer = printer;
        this.reader = reader;
        this.authorizer = authorizer;
    }

    public Map<String,Book> getBooks() {
        return books;
    }

    public Map<String,Movie> getMovies() {
        return movies;
    }

    public void addBook(String title) {
        books.put(title, new Book(title));
    }

    public void addMovie(Movie movie) {
        movies.put("title", movie);
    }

    public void addUser(String password) throws LibraryIdOverflow {
        authorizer.addUser(password);
    }

    private void chosenOption(UserInputOptions pressedKey) {
        switch (pressedKey) {
            case LOGIN:
                printer.printTypeUsername();
                String username = reader.readStringInput();
                printer.printTypePassword();
                String password = reader.readStringInput();
                if (authorizer.login(username, password)) {
                    printer.printLoginSuccessful();
                }
                else {
                    printer.printInvalidLogin();
                }
                break;
            case LIST_BOOKS:
                printer.printBooks(books);
                break;
            case RESERVE:
                if (authorizer.isUserLoggedIn())
                    tryReservation();
                else
                    printer.printNeedsToBeLoggedForThisOperation();
                break;
            case MEMBERSHIP_DETAILS:
                if (authorizer.isUserLoggedIn())
                    printer.printMembershipDetails(authorizer.getLoggedUser());
                else
                    printer.printMembershipDetails();
                break;
            case LIST_MOVIES:
                printer.printMovieCatalog(movies);
                break;
            case EXIT:
                printer.printExitMessage();
                shouldKeepRunningBiblioteca = false;
                break;
            case LOGOUT:
                shouldKeepRunningBiblioteca = false;
                break;
            default:
                printer.printInvalidOption();
                break;
        }
        if (pressedKey != UserInputOptions.EXIT && pressedKey != UserInputOptions.LOGOUT)
            printer.printMenuOptions();
    }

    private void tryReservation() {
        printer.printWhatIsTheBookTitle();
        String title = reader.readStringInput();
        Book bookToReserve = books.get(title);
        if (isPossibleToReserve(bookToReserve)) {
            bookToReserve.setIsReserved(true);
            printer.printBookReservedSuccessfully();
        }
        else {
            printer.printBookIsNotAvailable();
        }
    }

    private boolean isPossibleToReserve(Book book) {
        return book != null && !book.isReserved();
    }

    public void run() {
        printer.printWelcomeMessage();
        printer.printMenuOptions();
        while (shouldKeepRunningBiblioteca) {
            UserInputOptions pressedKey = reader.readUserSelection();
            chosenOption(pressedKey);
        }
    }
}
